package top.cwk.listener;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

import org.apache.log4j.Logger;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import top.cwk.api.common.IMemcachedService;

/**
 * 
 * <p>Title: SessionListener，session监听器</p>
 * <p>Description:描述 </p>
 * <p>Company: CHNI</p> 
 * @author 陈维康
 * @date 2017年8月25日
 */
public class SessionListener  implements 
                            HttpSessionListener,ServletContextListener {

	//保存sessionID和username的映射  
	public  static  Map<String, String> sessionMap = new HashMap<String, String>();
	
	private static IMemcachedService memcachedService;
	
	private static Logger logger = Logger.getLogger(SessionListener.class);
	
	/**
	 *  
	 * Description: 通过登录名判断用户是否存在
	 * @author: chenwk
	 * @date: 2016年9月21日
	 * @param sessionUserName
	 * @return
	 * @throws Exception
	 */
    public static  boolean isContainsSessionID(String sessionid) {  
    	return sessionMap.containsKey(sessionid);
    }  
    
    public static  boolean isContainsUsername(String username) {  
    	return sessionMap.containsValue(username);
    }  
    
    
    public static boolean replaceLogin(HttpSession session,String sessionUserName){
    	initSessionList();
    	String key = SessionListener.getSessionIDByUsername(sessionUserName);
    	 //强制登录，移除当前已登录的用户
    	 sessionMap.remove(key);
    	 //放入新的sessionid和username
    	 sessionMap.put(session.getId(),sessionUserName);
    	 logger.info("用户 ["+sessionUserName+"] 强制登录,移除已登录的sessionid:"+key);
    	 //刷新session列表
		 return flashSessionList();
    }
         
    /**
     * 
     * Description: 缓存用户session
     * @author: 陈维康
     * @date: 2016年9月21日
     * @param session session对象
     * @param sessionUserName 用户名
     * @throws Exception
     */
	 public static boolean createUserSession(HttpSession session,String sessionUserName)  {  
		 initSessionList();
		 sessionMap.put(session.getId(),sessionUserName);
		 return flashSessionList();
	 }
		 
	 
	 /**
	  * 
	  * Description: 移除缓存集合中的用户session
	  * @author: chenwk
	  * @date: 2016年9月21日
	  * @param sessionUserName
	  * @throws Exception
	  */
      public static void removeUserSession(String sessionUserName) {  
    	  initSessionList();
    	  Set<Map.Entry<String,String>> set = sessionMap.entrySet();
    	  Iterator<Map.Entry<String, String>> iter = set.iterator();
          while (iter.hasNext()) {
        	  Entry<String, String> next = iter.next();
        	  String val = next.getValue();
        	  if(val.equals(sessionUserName)){
        		  //移除当前用户
        		  String key =  next.getKey();
        		  sessionMap.remove(key);
        		  logger.info("用户 ["+sessionUserName +"] 退出登录,sessionid:"+key);
        		  break;
        	  }
          }
           flashSessionList();   
      }  
      
      /**
       * 
       * Description:通过登录用户名，获取存储的sessionid
       * @author:chenwk
       * @date: 2017年8月24日
       * @param sessionUserName
       * @return
       */
      public static String getSessionIDByUsername(String sessionUserName){
    	  Set<Map.Entry<String,String>> set = sessionMap.entrySet();
    	  Iterator<Map.Entry<String, String>> iter = set.iterator();
          String key = "";
    	  while (iter.hasNext()){  
    		  Entry<String, String> next = iter.next();
    		  String val = next.getValue();
              if((val).equals(sessionUserName)){  
            	  key =  next.getKey();
                  break;
              }  
           }  
    	  return key;
      }
	
      
      
      private static  void  initSessionList(){
    	  @SuppressWarnings("unchecked")
			Map<String,String> retMap = (Map<String, String>) memcachedService.get("sessionMap");
	    	  if(retMap!=null){
	  			sessionMap = retMap;
	  		}
      }
      
	/**
	 * 
	 * Description:同步sessionMap
	 * @author: chenwk
	 * @date: 2016年9月21日
	 * @return
	 */
	private static  boolean  flashSessionList(){
		forachSessionMap();
		return memcachedService.addForeverSessionMap("sessionMap", sessionMap);
	}
	
	public static  void  clearSessionList(){
		sessionMap = new HashMap<String,String>();
		memcachedService.addForeverSessionMap("sessionMap", sessionMap);
	}
	
	/**************************session监听器实现方法*******************************/
    
	/**
     * session销毁时触发此事件
     * 移除集合中的session
     */
	@Override
	public void sessionDestroyed(HttpSessionEvent sessionEvent) {
		initSessionList();
		String key = sessionEvent.getSession().getId();
		logger.info("session过期移除用户："+sessionMap.get(key)+":"+key);
		sessionMap.remove(key);  
		flashSessionList();
	}
	
	@Override
	public void sessionCreated(HttpSessionEvent sessionEvent) {}
	
	/***************容器初始化 获取memcachedService bean *****************/
	
	@Override
	public void contextDestroyed(ServletContextEvent sec) { }

	@Override
	public void contextInitialized(ServletContextEvent sec) {
		WebApplicationContext appctx = WebApplicationContextUtils.
				getWebApplicationContext(sec.getServletContext());
		logger.info("系统启动,初始化memcachedService...");
		memcachedService = appctx.getBean(IMemcachedService.class);
		@SuppressWarnings("unchecked")
		Map<String,String> retMap = (Map<String, String>) memcachedService.get("sessionMap");
		if(retMap==null){
			memcachedService.addForeverSessionMap("sessionMap", sessionMap);
		}else{
			sessionMap = retMap;
		}
		
	}


	private static  void forachSessionMap(){
    	  Set<Map.Entry<String,String>> set = sessionMap.entrySet();
    	  Iterator<Map.Entry<String, String>> iter = set.iterator();
          logger.info("当前sessionMap中的用户：");
    	  while (iter.hasNext()) {
        	  Entry<String, String> next = iter.next();
        	  String key = next.getKey();
        	  String val = next.getValue();
        	  logger.info("key:"+key+",value:"+val);
    	  }
      }
	
}
